const-hex
This crate provides a fast conversion of byte arrays to hexadecimal strings, both at compile time, and at run time.
It aims to be a drop-in replacement for the hex
crate, as well as extending
the API with const-eval, a const-generics formatting buffer, similar
to itoa
's, and more.
Version requirement: rustc 1.64+
Performance
This crate offers performance comparable to faster-hex
on x86
/x86-64
architectures but outperforms it on other platforms, as faster-hex
is
only optimized for x86
/x86-64
.
This crate is 10 to 50 times faster than hex
in encoding and decoding, and
100+ times faster than libstd
in formatting.
The following benchmarks were ran on an AMD Ryzen 9 7950X, compiled with
1.83.0-nightly (9e394f551 2024-09-25)
on x86_64-unknown-linux-gnu
.
You can run these benchmarks with cargo bench --features std
on a nightly
compiler.
test check::const_hex::bench1_32b ... bench: 2.85 ns/iter (+/- 0.44)
test check::const_hex::bench2_256b ... bench: 15.36 ns/iter (+/- 0.44)
test check::const_hex::bench3_2k ... bench: 117.55 ns/iter (+/- 1.72)
test check::const_hex::bench4_16k ... bench: 915.78 ns/iter (+/- 56.34)
test check::const_hex::bench5_128k ... bench: 7,269.26 ns/iter (+/- 80.62)
test check::const_hex::bench6_1m ... bench: 58,975.63 ns/iter (+/- 707.02)
test check::faster_hex::bench1_32b ... bench: 2.70 ns/iter (+/- 0.01)
test check::faster_hex::bench2_256b ... bench: 14.45 ns/iter (+/- 1.44)
test check::faster_hex::bench3_2k ... bench: 123.58 ns/iter (+/- 1.09)
test check::faster_hex::bench4_16k ... bench: 960.32 ns/iter (+/- 6.34)
test check::faster_hex::bench5_128k ... bench: 7,709.14 ns/iter (+/- 77.69)
test check::faster_hex::bench6_1m ... bench: 62,165.54 ns/iter (+/- 1,167.78)
test check::naive::bench1_32b ... bench: 16.41 ns/iter (+/- 1.90)
test check::naive::bench2_256b ... bench: 221.25 ns/iter (+/- 3.47)
test check::naive::bench3_2k ... bench: 2,493.23 ns/iter (+/- 154.04)
test check::naive::bench4_16k ... bench: 16,221.81 ns/iter (+/- 384.98)
test check::naive::bench5_128k ... bench: 485,588.59 ns/iter (+/- 10,260.00)
test check::naive::bench6_1m ... bench: 3,895,089.20 ns/iter (+/- 45,589.05)
test decode::const_hex::bench1_32b ... bench: 17.33 ns/iter (+/- 0.38)
test decode::const_hex::bench2_256b ... bench: 38.17 ns/iter (+/- 1.07)
test decode::const_hex::bench3_2k ... bench: 235.07 ns/iter (+/- 3.27)
test decode::const_hex::bench4_16k ... bench: 1,681.14 ns/iter (+/- 17.25)
test decode::const_hex::bench5_128k ... bench: 13,097.65 ns/iter (+/- 101.14)
test decode::const_hex::bench6_1m ... bench: 105,945.60 ns/iter (+/- 2,703.49)
test decode::faster_hex::bench1_32b ... bench: 17.91 ns/iter (+/- 0.40)
test decode::faster_hex::bench2_256b ... bench: 54.53 ns/iter (+/- 1.41)
test decode::faster_hex::bench3_2k ... bench: 245.35 ns/iter (+/- 3.89)
test decode::faster_hex::bench4_16k ... bench: 1,836.62 ns/iter (+/- 25.01)
test decode::faster_hex::bench5_128k ... bench: 14,471.53 ns/iter (+/- 184.29)
test decode::faster_hex::bench6_1m ... bench: 116,688.27 ns/iter (+/- 1,539.72)
test decode::hex::bench1_32b ... bench: 109.14 ns/iter (+/- 1.88)
test decode::hex::bench2_256b ... bench: 712.92 ns/iter (+/- 14.25)
test decode::hex::bench3_2k ... bench: 5,196.66 ns/iter (+/- 102.67)
test decode::hex::bench4_16k ... bench: 41,308.30 ns/iter (+/- 917.60)
test decode::hex::bench5_128k ... bench: 786,648.00 ns/iter (+/- 6,589.60)
test decode::hex::bench6_1m ... bench: 6,316,271.50 ns/iter (+/- 22,712.18)
test decode_to_slice::const_hex::bench1_32b ... bench: 5.14 ns/iter (+/- 0.39)
test decode_to_slice::const_hex::bench2_256b ... bench: 26.18 ns/iter (+/- 0.26)
test decode_to_slice::const_hex::bench3_2k ... bench: 206.71 ns/iter (+/- 1.88)
test decode_to_slice::const_hex::bench4_16k ... bench: 1,666.49 ns/iter (+/- 15.67)
test decode_to_slice::const_hex::bench5_128k ... bench: 12,979.03 ns/iter (+/- 80.40)
test decode_to_slice::const_hex::bench6_1m ... bench: 107,213.20 ns/iter (+/- 4,024.91)
test decode_to_slice::faster_hex::bench1_32b ... bench: 6.51 ns/iter (+/- 0.04)
test decode_to_slice::faster_hex::bench2_256b ... bench: 28.66 ns/iter (+/- 0.29)
test decode_to_slice::faster_hex::bench3_2k ... bench: 217.84 ns/iter (+/- 1.03)
test decode_to_slice::faster_hex::bench4_16k ... bench: 1,730.89 ns/iter (+/- 19.36)
test decode_to_slice::faster_hex::bench5_128k ... bench: 13,439.63 ns/iter (+/- 92.19)
test decode_to_slice::faster_hex::bench6_1m ... bench: 109,432.90 ns/iter (+/- 1,526.01)
test decode_to_slice::hex::bench1_32b ... bench: 38.44 ns/iter (+/- 1.30)
test decode_to_slice::hex::bench2_256b ... bench: 290.78 ns/iter (+/- 16.09)
test decode_to_slice::hex::bench3_2k ... bench: 2,663.51 ns/iter (+/- 48.22)
test decode_to_slice::hex::bench4_16k ... bench: 19,016.95 ns/iter (+/- 514.35)
test decode_to_slice::hex::bench5_128k ... bench: 612,840.31 ns/iter (+/- 6,561.70)
test decode_to_slice::hex::bench6_1m ... bench: 5,098,572.75 ns/iter (+/- 120,113.94)
test encode::const_hex::bench1_32b ... bench: 6.94 ns/iter (+/- 0.06)
test encode::const_hex::bench2_256b ... bench: 11.84 ns/iter (+/- 0.07)
test encode::const_hex::bench3_2k ... bench: 78.36 ns/iter (+/- 0.89)
test encode::const_hex::bench4_16k ... bench: 475.29 ns/iter (+/- 11.56)
test encode::const_hex::bench5_128k ... bench: 3,577.27 ns/iter (+/- 70.48)
test encode::const_hex::bench6_1m ... bench: 29,996.00 ns/iter (+/- 668.44)
test encode::faster_hex::bench1_32b ... bench: 17.31 ns/iter (+/- 0.37)
test encode::faster_hex::bench2_256b ... bench: 39.39 ns/iter (+/- 0.76)
test encode::faster_hex::bench3_2k ... bench: 106.60 ns/iter (+/- 1.41)
test encode::faster_hex::bench4_16k ... bench: 653.21 ns/iter (+/- 5.40)
test encode::faster_hex::bench5_128k ... bench: 5,260.68 ns/iter (+/- 88.46)
test encode::faster_hex::bench6_1m ... bench: 44,520.36 ns/iter (+/- 1,200.74)
test encode::hex::bench1_32b ... bench: 102.77 ns/iter (+/- 0.82)
test encode::hex::bench2_256b ... bench: 720.90 ns/iter (+/- 22.52)
test encode::hex::bench3_2k ... bench: 5,672.44 ns/iter (+/- 287.53)
test encode::hex::bench4_16k ... bench: 38,988.71 ns/iter (+/- 6,457.99)
test encode::hex::bench5_128k ... bench: 364,376.25 ns/iter (+/- 51,416.85)
test encode::hex::bench6_1m ... bench: 2,959,499.88 ns/iter (+/- 410,006.38)
test encode_to_slice::const_hex::bench1_32b ... bench: 1.56 ns/iter (+/- 0.00)
test encode_to_slice::const_hex::bench2_256b ... bench: 6.75 ns/iter (+/- 0.03)
test encode_to_slice::const_hex::bench3_2k ... bench: 58.32 ns/iter (+/- 0.23)
test encode_to_slice::const_hex::bench4_16k ... bench: 518.24 ns/iter (+/- 4.91)
test encode_to_slice::const_hex::bench5_128k ... bench: 4,003.77 ns/iter (+/- 28.57)
test encode_to_slice::const_hex::bench6_1m ... bench: 34,519.64 ns/iter (+/- 656.35)
test encode_to_slice::faster_hex::bench1_32b ... bench: 4.54 ns/iter (+/- 0.01)
test encode_to_slice::faster_hex::bench2_256b ... bench: 8.11 ns/iter (+/- 0.05)
test encode_to_slice::faster_hex::bench3_2k ... bench: 52.10 ns/iter (+/- 0.64)
test encode_to_slice::faster_hex::bench4_16k ... bench: 475.81 ns/iter (+/- 6.50)
test encode_to_slice::faster_hex::bench5_128k ... bench: 3,425.49 ns/iter (+/- 15.01)
test encode_to_slice::faster_hex::bench6_1m ... bench: 28,725.82 ns/iter (+/- 839.95)
test encode_to_slice::hex::bench1_32b ... bench: 12.01 ns/iter (+/- 0.12)
test encode_to_slice::hex::bench2_256b ... bench: 121.68 ns/iter (+/- 1.98)
test encode_to_slice::hex::bench3_2k ... bench: 989.33 ns/iter (+/- 3.83)
test encode_to_slice::hex::bench4_16k ... bench: 8,087.93 ns/iter (+/- 25.25)
test encode_to_slice::hex::bench5_128k ... bench: 64,323.94 ns/iter (+/- 249.97)
test encode_to_slice::hex::bench6_1m ... bench: 515,710.80 ns/iter (+/- 2,232.59)
test format::const_hex::bench1_32b ... bench: 10.26 ns/iter (+/- 0.19)
test format::const_hex::bench2_256b ... bench: 18.28 ns/iter (+/- 0.86)
test format::const_hex::bench3_2k ... bench: 116.95 ns/iter (+/- 2.17)
test format::const_hex::bench4_16k ... bench: 1,122.29 ns/iter (+/- 6.25)
test format::const_hex::bench5_128k ... bench: 8,903.81 ns/iter (+/- 111.29)
test format::const_hex::bench6_1m ... bench: 77,476.15 ns/iter (+/- 1,498.93)
test format::std::bench1_32b ... bench: 370.27 ns/iter (+/- 2.52)
test format::std::bench2_256b ... bench: 2,910.66 ns/iter (+/- 40.35)
test format::std::bench3_2k ... bench: 22,554.52 ns/iter (+/- 263.93)
test format::std::bench4_16k ... bench: 182,692.06 ns/iter (+/- 3,494.64)
test format::std::bench5_128k ... bench: 1,475,988.90 ns/iter (+/- 21,895.90)
test format::std::bench6_1m ... bench: 11,834,234.60 ns/iter (+/- 139,230.20)
Acknowledgements
hex
for the initial encoding/decoding implementationsfaster-hex
for thex86
/x86-64
check and decode implementations- dtolnay/itoa for the initial crate/library API layout